"""
    逻辑回归：将线性回归函数的输出，作为Sigmoid函数的输入，然后输出为0-1之间的
"""


import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report


def LR():
    # 加载数据集
    cancer = pd.read_csv("./Prostate_Cancer.csv")
    pd.set_option("display.max_columns", None)
    #print(cancer)
    print(cancer.head(5))
    # id(标识),diagnosis_result(M恶性,B良性),radius(半径),texture(纹理),
    # perimeter(周长),area(面积),smoothness(平滑程度),compactness(紧密度),
    # symmetry(对称性),fractal_dimension(分形维数)
    print("特征值名称：", list(cancer.columns))

    # 提取特征值和目标值
    feature = cancer[list(cancer.columns)[2:]]
    print("特征值", feature.head(5))
    target = cancer[list(cancer.columns)[1]]
    print("目标值", target.head(5))

    # 将目标值进行0-1化 恶性肿瘤替换为1，量性肿瘤替换为0
    target.replace("M", 1, inplace=True)
    target.replace("B", 0, inplace=True)
    print(target.head(5))

    # 划分数据集 测试集设置25%的数据量
    x_train, x_test, y_train, y_test = train_test_split(feature, target, test_size=0.25, shuffle=True)
    #x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, test_size=0.25, shuffle=True)
    print("训练集：", x_train.shape, y_train.shape)
    #print("验证集：", x_val.shape, y_val.shape)
    print("测试集：", x_test.shape, y_test.shape)

    # 标准化
    '''
    (1) 功能：将数据的分布转为正态分布。
		事实上，就是标准分数。标准化之后，每个特征的值变为均值为0，方差为1
	(2) 目的：
		将特征表现为标准正态分布数据(均值为0，方差为1)。
		如果某个特征的方差比其他特征大几个数量级，那么它就会在学习算法中占据主导位置，导致学习器不能从其他特征中学习，从而降低精度。
		加快梯度下降求解的速度。
    '''
    std = StandardScaler()
    x_train= std.fit_transform(x_train)
    #x_train = std.fit_transform(x_train)
    #x_val = std.transform(x_val)
    x_test = std.fit_transform(x_test)
    x_all = std.fit_transform(feature)
    

    # 建立模型
    lg = LogisticRegression()
    # 训练 进行模型的拟合
    lg.fit(x_train, y_train)
    #lg.fit(x_train,target)
    # 验证 为模型打分
    #score_val = lg.score(x_val, y_val)
    #print("在验证集上的得分：", score_val)
    # 测试 测试上面的打分
    score_test = lg.score(x_test, y_test)
    print("在测试集上的得分：", score_test)
    # 预测······················
    predict = lg.predict(x_test)
    print("预测值：", list(predict))
    print('实际值：', list(y_test))
    # 打印召回率，F1
    print(classification_report(y_test, predict, labels=[0, 1], target_names=["良性", "恶性"]))


if __name__ == "__main__":
    LR()